图的广度优先遍历,基于邻接链表实现

#include <iostream>
#include <queue>
#include <stack>


using namespace std;


/***************************************
 *  * 图的深度优先遍历
 *   * 基于邻接链表的非递归实现
 *    **************************************/


typedef char vertex_t;  //结点数据类型


//边结点
typedef struct _tag_edge_node_t
{
    int node_num;  //边终点所在数组序号
    _tag_edge_node_t* next_node;  //下一条边
}edge_node_t;


//顶点结点
typedef struct _tag_head_node_t
{
    vertex_t data;  //结点数据
    edge_node_t* first_edge;  //第一条边
}head_node_t;


#define MAX_NUMBER 20  //图中最大结点数目


//图结构
typedef struct _tag_graph_t
{
    head_node_t head_data[MAX_NUMBER];  //顶点数组
    unsigned int head_node_count;  //顶点数目
}graph_t;


void create_adjacency_list(graph_t* graph)
{
    edge_node_t* p_edge = NULL;
    if (graph == NULL)
        return;


    graph->head_node_count = 6;
    for (unsigned int i = 0; i < graph->head_node_count; ++i)
    {
        graph->head_data[i].data = 'A' + i;
        graph->head_data[i].first_edge = NULL;
    }


    graph->head_data[0].first_edge = new edge_node_t;
    p_edge = graph->head_data[0].first_edge;
    p_edge->node_num = 2;

    p_edge->next_node = new edge_node_t;
    p_edge = p_edge->next_node;
    p_edge->node_num = 4;


    p_edge->next_node = new edge_node_t;
    p_edge = p_edge->next_node;
    p_edge->node_num = 5;
    p_edge->next_node = NULL;


    graph->head_data[1].first_edge = new edge_node_t;
    graph->head_data[1].first_edge->node_num = 2;
    graph->head_data[1].first_edge->next_node = NULL;


    graph->head_data[2].first_edge = new edge_node_t;
    graph->head_data[2].first_edge->node_num = 3;
    graph->head_data[2].first_edge->next_node = NULL;


    graph->head_data[3].first_edge = new edge_node_t;
    graph->head_data[3].first_edge->node_num = 5;
    graph->head_data[3].first_edge->next_node = NULL;


    graph->head_data[4].first_edge = new edge_node_t;
    graph->head_data[4].first_edge->node_num = 1;
    graph->head_data[4].first_edge->next_node = 
        new edge_node_t;

    p_edge = graph->head_data[4].first_edge->next_node;
    p_edge->node_num = 3;
    p_edge->next_node = new edge_node_t;

    p_edge = p_edge->next_node;
    p_edge->node_num = 5;
    p_edge->next_node = NULL;
}

void breadth_first_search(graph_t *graph, int start_pos)
{
    queue<int> visit_queue;  //访问队列
    bool is_visit[MAX_NUMBER];  //访问标志数组
    for (int i = 0; i < MAX_NUMBER; ++i)
        is_visit[i] = false;

    for (unsigned int i = 0; i < graph->head_node_count; 
            ++i)
    {
        if (!is_visit[i])  //该结点没有被访问
            visit_queue.push(i);

        while (!visit_queue.empty())
        {
            //出队
            int n_pos = visit_queue.front();
            visit_queue.pop();
            if (!is_visit[n_pos])
            {
                cout<<graph->head_data[n_pos].data<<endl;
                is_visit[n_pos] = true;

                //将该结点下所有未被访问的边入队
                edge_node_t *next = 
                    graph->head_data[n_pos].first_edge;
                while (next != NULL)
                {
                    if (!is_visit[next->node_num])
                        visit_queue.push(next->node_num);
                    next = next->next_node;
                }
            }
        }
    }
}

void depth_first_search(graph_t* graph, int start_pos)
{
    stack<int> visit_node;
    bool is_visit[MAX_NUMBER];  //访问标志数组
    for (int i = 0; i < MAX_NUMBER; ++i)
        is_visit[i] = false;


    cout<<graph->head_data[start_pos].data<<endl;
    is_visit[start_pos] = true;
    visit_node.push(start_pos);  //将第一个元素压栈
    while (!visit_node.empty())
    {
        int num = visit_node.top();
        edge_node_t* next = graph->head_data[num].first_edge;
        for (; next != NULL; next = next->next_node)  //存在边,且该边的终点未被访问
        {
            if (!is_visit[next->node_num])
            {
                cout<<graph->head_data[next->node_num].data<<endl;
                is_visit[next->node_num] = true;
                visit_node.push(next->node_num);
                break;
            }
        }
        if (next == NULL)  //以该结点为起点的所有终点访问完毕
            visit_node.pop();
    }
}

int main(int argc, char* argv[])
{
    graph_t graph;
    create_adjacency_list(&graph);
    //depth_first_search(&graph, 0);
    breadth_first_search(&graph, 0);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 邻接表是一种表示的数据结构,它由一个数组和一个链表组成。数组中的每个元素表示一个顶点,链表中的每个节点表示该顶点的邻居。 深度优先遍历(DFS)是一种遍历的算法,它从一个顶点开始,沿着一条路径一直走到底,直到不能再走为止,然后回溯到前一个顶点,继续走其他路径,直到所有的顶点都被访问过。 广度优先遍历(BFS)是一种遍历的算法,它从一个顶点开始,先访问它的所有邻居,然后再访问邻居的邻居,直到所有的顶点都被访问过。 邻接表可以很方便地实现的深度优先遍历和广度优先遍历。对于深度优先遍历,我们可以使用递归函数来实现,从一个顶点开始,依次访问它的邻居,如果邻居还没有被访问过,则递归访问邻居。对于广度优先遍历,我们可以使用队列来实现,从一个顶点开始,先将它的所有邻居加入队列中,然后依次访问队列中的顶点,将它们的邻居加入队列中,直到队列为空为止。 ### 回答2: 邻接表是一种表示的数据结构,它以链表的形式存储每一个顶点的邻接点。使用邻接实现的深度优先遍历和广度优先遍历是常见的操作。 深度优先遍历(Depth First Search, DFS)可以理解为沿着一个路径走到底,直到走到末端再回溯。具体实现中,我们可以先访问起点,然后递归地遍历与其相邻的所有未访问的顶点。可以用栈来保存待遍历的顶点,每次从栈顶取出一个顶点继续遍历相邻的顶点。 广度优先遍历(Breadth First Search,BFS)可以理解为一层一层遍历,先访问当前节点所有未被访问的且未入队的邻接点,并将其入队。然后依次取出队首元素,继续进行访问和入队操作。可以用队列来保存待遍历的顶点。 邻接实现深度优先遍历的伪代码: ```python def dfs(graph, start): visited = set() # 记录访问过的节点 stack = [start] # 初始状态下栈中只有起点 while stack: # 当栈不为空时 vertex = stack.pop() # 取出栈顶元素 if vertex not in visited: visited.add(vertex) # 标记为访问过 for neighbor in graph[vertex]: # 遍历vertex的邻接点neighbor if neighbor not in visited: stack.append(neighbor) # 将未访问过的邻接点加入栈中 return visited ``` 邻接实现广度优先遍历的伪代码: ```python from collections import deque def bfs(graph, start): visited = set() # 记录访问过的节点 queue = deque([start]) # 初始状态下队列中只有起点 while queue: # 当队列不为空时 vertex = queue.popleft() # 取出队首元素 if vertex not in visited: visited.add(vertex) # 标记为访问过 for neighbor in graph[vertex]: # 遍历vertex的邻接点neighbor if neighbor not in visited: queue.append(neighbor) # 将未访问过的邻接点加入队列中 return visited ``` 邻接表的深度优先遍历和广度优先遍历的时间复杂度都是O(V+E),其中V为中的顶点数,E为边数。在实际应用中,要根据具体情况选择合适的算法来遍历。 ### 回答3: 邻接表是的一种存储方式,它以每个顶点为索引,每个索引对应一个链表链表中存储该顶点相邻的其他顶点。这种存储方式适合解决大规模的问题,因为其空间复杂度与中的边数成正比。 深度优先遍历(DFS)是的一种遍历方式,它从一个顶点开始,访问该顶点的直接邻居,对邻居中未访问的顶点又进行相同的操作。当一个顶点没有未访问的邻居时,回溯到之前的顶点继续遍历。邻接实现DFS可以使用递归实现,即从某个顶点开始,递归访问其邻居,直到没有未访问的邻居。 广度优先遍历(BFS)则是另一种遍历方式,它从一个顶点开始,先访问其直接邻居,再依次访问邻居的邻居,直到遍历完所有的顶点。邻接实现BFS可以使用队列实现,即从某个顶点开始,将其邻居加入队列中,依次出队并访问其邻居,直到队列为空。 需要注意的是,在使用邻接实现的遍历时,需要标记每个顶点是否被访问过,避免重复遍历和死循环。同时需要注意DFS和BFS的时间复杂度,DFS的时间复杂度为O(V+E),BFS的时间复杂度为O(V+E),其中V表示顶点数,E表示边数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值